import { createRef, RefObject } from 'react'
import type { Result } from 'ahooks/lib/useRequest/src/types'
import { create } from 'zustand'
import { AgGridReact } from '@ag-grid-community/react'

import { DEFAULT_PAGE_SIZE } from '@/utils/pagination'
import { IEventTemplateEnableRes } from '@oBiz/components/EventSelect/api'
import { apiWaybillRecordTabCount } from './apis'
import {
  IEventTemplateBatchActionForm,
  ISetBatchPublishFirstLegInformationReq,
  ISetBatchPublishLastLegInformationReq,
  ISetBatchPublishLogisticsChannelReq,
  IUpdateFirstLineBatchActionForm,
  IUpdateServiceLevelBatchActionForm,
  IUpdateTailLinesBatchActionForm,
  IWaybillRecordItem,
  IWaybillRecordItemWithIndex,
  IWaybillRecordListReq,
  IWaybillRecordListRes,
  IWaybillRecordTabCountRes,
} from './interface'

export type TRequest = Result<IWaybillRecordListRes, [IWaybillRecordListReq]>

export type TUpdateBatchPublishReq = Partial<ISetBatchPublishLogisticsChannelReq> &
  Partial<ISetBatchPublishFirstLegInformationReq> &
  Partial<ISetBatchPublishLastLegInformationReq>

export type TBatchAddFormValueProps = Partial<IEventTemplateBatchActionForm> &
  Partial<IUpdateFirstLineBatchActionForm> &
  Partial<IUpdateTailLinesBatchActionForm> &
  Partial<IUpdateServiceLevelBatchActionForm>

// AbortController（TabCount 专用）
let tabCountController: AbortController | null = null

export interface IStore {
  // 表格操作
  gridRef: RefObject<AgGridReact<IWaybillRecordItem>>
  request?: TRequest
  reqData: IWaybillRecordListReq
  setReqData: (
    val: Partial<IWaybillRecordListReq> | ((prevVal: IWaybillRecordListReq) => IWaybillRecordListReq),
  ) => void
  getData: (scrollToTop?: boolean) => void
  tabCountLoading: boolean
  tabCount: IWaybillRecordTabCountRes
  // 运单页签数据
  getTabCount: (reqData: IWaybillRecordListReq) => void
  selectedKeys: string[]
  setSelectedKeys: (keys: string[]) => void
  // 批量修改弹窗
  waybillList: IWaybillRecordItemWithIndex[]
  setWaybillList: (val: IWaybillRecordItemWithIndex[]) => void
  batchAddFormValue: TBatchAddFormValueProps
  setBatchAddFormValue: (value: TBatchAddFormValueProps) => void
  // 轨迹模版
  eventList: IEventTemplateEnableRes[]
  setEventList: (val: IEventTemplateEnableRes[]) => void
}

export const defaultParams: IWaybillRecordListReq = {
  page: 1,
  size: DEFAULT_PAGE_SIZE,
  tabId: 0,
  searchField: 1,
  searchWords: undefined,
  shipmentDateStart: undefined,
  shipmentDateStartEnd: undefined,
  gangHouUserIds: undefined,
  businessUserIds: undefined,
  logisticsChannelIds: undefined,
  merchantIds: undefined,
}

export const useBoundStore = create<IStore>((set, get) => {
  return {
    // 表格操作
    selectedKeys: [],
    setSelectedKeys: keys => {
      set({ selectedKeys: keys })
    },
    gridRef: createRef(),
    reqData: { ...defaultParams },
    setReqData: val => {
      set(prev => {
        return {
          reqData: {
            ...prev.reqData,
            ...(typeof val === 'function' ? val(prev.reqData) : val),
          },
        }
      })
    },
    getData: scrollToTop => {
      const { gridRef, request, reqData, getTabCount } = get()
      request?.run(reqData)
      getTabCount(reqData)
      if (scrollToTop) gridRef.current?.api?.ensureIndexVisible(0, 'top')
    },
    // 运单页签数据
    tabCountLoading: false,
    tabCount: [],
    getTabCount: (reqData: IWaybillRecordListReq) => {
      const { tabCountLoading } = get()
      if (tabCountLoading) return
      tabCountController?.abort()
      tabCountController = new AbortController()
      set({ tabCountLoading: true })
      apiWaybillRecordTabCount(reqData, tabCountController.signal)
        .then(data => {
          set({ tabCountLoading: false, tabCount: data || null })
        })
        .catch(() => {
          set({ tabCountLoading: false })
        })
    },
    // 轨迹弹窗
    batchAddFormValue: {},
    setBatchAddFormValue: (val: TBatchAddFormValueProps) => {
      set({ batchAddFormValue: { ...val } })
    },
    // 轨迹模版
    eventList: [],
    setEventList: (val: IEventTemplateEnableRes[]) => {
      set({ eventList: val })
    },
    // 批量修改弹窗列表数据源
    waybillList: [],
    setWaybillList: (val: IWaybillRecordItem[]) => {
      set({ waybillList: val })
    },
  }
})
